#include "SymbolTable.hpp"

#include "ProgramManager.hpp"

#include <iostream>
#include <iomanip>

SymbolTable::SymbolTable ()
{
}

SymbolTable::~SymbolTable ()
{
}

void
SymbolTable::registerSymbol ( unsigned int index )
{
    Type terr; terr._base = TYPE_ERROR; terr._modifier = NONE; terr._size = 0;
    _indexToCategory [ index ] = CLASS_ERROR;
    _indexToType [ index ] = terr;
}

SymbolClass
SymbolTable::getCategoryOf ( const unsigned int index ) const
{
    if ( _indexToCategory.find ( index ) != _indexToCategory.end () )
        return _indexToCategory.find ( index )->second;
    return CLASS_ERROR;
}

void
SymbolTable::setCategoryOf ( const unsigned int index, const SymbolClass category )
{
    _indexToCategory [ index ] = category;
}

Type
SymbolTable::getTypeOf ( const unsigned int index ) const
{
    Type terr; terr._base = TYPE_ERROR; terr._modifier = NONE; terr._size = 0;
    if ( _indexToType.find ( index ) != _indexToType.end () )
        return _indexToType.find ( index )->second;
    return terr;
}

void
SymbolTable::setTypeOf ( const unsigned int index, const Type type )
{
    _indexToType [ index ] = type;
}

void
SymbolTable::display () const
{
    for ( std::map < unsigned int, SymbolClass >::const_iterator it = _indexToCategory.begin () ;
          it != _indexToCategory.end () ; ++ it )
    {
        Type type = _indexToType.find ( it->first )->second;
        std::cout << it->second << " " << type._base << " ";
        switch ( type._modifier )
        {
        case NONE:
            std::cout << ProgramManager::getNameOf ( it->first );
            break;
        case POINTER:
            std::cout << "*" << ProgramManager::getNameOf ( it->first );
            break;
        case ARRAY:
            std::cout << ProgramManager::getNameOf ( it->first ) << " [ " << type._size << " ]";
            break;
        }
        std::cout << std::endl;
    }
}

